<html>
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<head>
<title>Section 10.5.&nbsp; Interrupted System Calls</title>
<link rel="STYLESHEET" type="text/css" href="images/style.css">
<link rel="STYLESHEET" type="text/css" href="images/docsafari.css">
</head>
<body>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/team.gif" width="60" height="17" border="0" align="absmiddle"  alt="Team BBL"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=ch10lev1sec4.html><img src="images/prev.gif" width="60" height="17" border="0" align="absmiddle" alt="Previous Page"></a>
<a href=ch10lev1sec6.html><img src="images/next.gif" width="60" height="17" border="0" align="absmiddle" alt="Next Page"></a>
</div></td></tr></table>
<br><table width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td valign="top"><a name="ch10lev1sec5"></a>
<h3 class="docSection1Title">10.5. Interrupted System Calls</h3>
<p class="docText">A characteristic of earlier UNIX systems is that if a process caught a signal while the process was blocked in a &quot;slow&quot; system call, the system call was interrupted. The system call returned an error and <tt>errno</tt> was set to <tt>EINTR</tt>. This was done under the assumption that since a signal occurred and the process caught it, there is a good chance that something has happened that should wake up the blocked system call.</P>
<blockquote>
<p class="docText">Here, we have to differentiate between a system call and a function. It is a system call within the kernel that is interrupted when a signal is caught.</P>
</blockquote>
<p class="docText">To support this feature, the system calls are divided into two categories: the &quot;slow&quot; system calls and all the others. The slow system calls are those that can block forever. Included in this category are</p>
<UL><LI><p class="docList">Reads that can block the caller forever if data isn't present with certain file types (pipes, terminal devices, and network devices)</P></li><LI><p class="docList">Writes that can block the caller forever if the data can't be accepted immediately by these same file types</P></LI><li><p class="docList">Opens that block until some condition occurs on certain file types (such as an open of a terminal device that waits until an attached modem answers the phone)</P></li><LI><p class="docList">The <tt>pause</tt> function (which by definition puts the calling process to sleep until a signal is caught) and the <tt>wait</tt> function</P></LI><li><p class="docList">Certain <tt>ioctl</tt> operations</P></LI><li><p class="docList">Some of the interprocess communication functions (<a class="docLink" href="ch15.html#ch15">Chapter 15</a>)</P></LI></ul>
<p class="docText">The notable exception to these slow system calls is anything related to disk I/O. Although a read or a write of a disk file can block the caller temporarily (while the disk driver queues the request and then the request is executed), unless a hardware error occurs, the I/O operation always returns and unblocks the caller quickly.</p>
<p class="docText">One condition that is handled by interrupted system calls, for example, is when a process initiates a read from a terminal device and the user at the terminal walks away from the terminal for an extended period. In this example, the process could be blocked for hours or days and would remain so unless the system was taken down.</p>
<blockquote>
<p class="docText"><a name="idd1e71074"></a><a name="idd1e71077"></a><a name="idd1e71080"></a><a name="idd1e71083"></a><a name="idd1e71088"></a><a name="idd1e71093"></a><a name="idd1e71096"></a><a name="idd1e71101"></a><a name="idd1e71106"></a><a name="idd1e71111"></a><a name="idd1e71116"></a><a name="idd1e71121"></a><a name="idd1e71124"></a><a name="idd1e71127"></a><a name="idd1e71132"></a><a name="idd1e71137"></a><a name="idd1e71142"></a><a name="idd1e71147"></a>POSIX.1 semantics for interrupted <tt>read</tt>s and <tt>write</tt>s changed with the 2001 version of the standard. Earlier versions gave implementations a choice for how to deal with <tt>read</tt>s and <tt>write</tt>s that have processed partial amounts of data. If <tt>read</tt> has received and transferred data to an application's buffer, but has not yet received all that the application requested and is then interrupted, the operating system could either fail the system call with <tt>errno</tt> set to <tt>EINTR</tt> or allow the system call to succeed, returning the partial amount of data received. Similarly, if <tt>write</tt> is interrupted after transferring some of the data in an application's buffer, the operation system could either fail the system call with <tt>errno</tt> set to <tt>EINTR</tt> or allow the system call to succeed, returning the partial amount of data written. Historically, implementations derived from System V fail the system call, whereas BSD-derived implementations return partial success. With the 2001 version of the POSIX.1 standard, the BSD-style semantics are required.</p>
</blockquote>
<p class="docText">The problem with interrupted system calls is that we now have to handle the error return explicitly. The typical code sequence (assuming a read operation and assuming that we want to restart the read even if it's interrupted) would be</P>

<pre>
    again:
        if ((n = read(fd, buf, BUFFSIZE)) &lt; 0) {
            if (errno == EINTR)
                goto again;     /* just an interrupted system call */
            /* handle other errors */
        }
</pre><br>

<p class="docText">To prevent applications from having to handle interrupted system calls, 4.2BSD introduced the automatic restarting of certain interrupted system calls. The system calls that were automatically restarted are <tt>ioctl</tt>, <tt>read</tt>, <tt>readv</tt>, <tt>write</tt>, <tt>writev</tt>, <tt>wait</tt>, and <tt>waitpid</tt>. As we've mentioned, the first five of these functions are interrupted by a signal only if they are operating on a slow device; <tt>wait</tt> and <tt>waitpid</tt> are always interrupted when a signal is caught. Since this caused a problem for some applications that didn't want the operation restarted if it was interrupted, 4.3BSD allowed the process to disable this feature on a per signal basis.</P>
<blockquote>
<p class="docText">POSIX.1 allows an implementation to restart system calls, but it is not required. The Single UNIX Specification defines the <tt>SA_RESTART</tt> flag as an XSI extension to <tt>sigaction</tt> to allow applications to request that interrupted system calls be restarted.</p>
<p class="docText">System V has never restarted system calls by default. BSD, on the other hand, restarts them if interrupted by signals. By default, FreeBSD 5.2.1, Linux 2.4.22, and Mac OS X 10.3 restart system calls interrupted by signals. The default on Solaris 9, however, is to return an error (<tt>EINTR</tt>) instead.</P>
</blockquote>
<p class="docText">One of the reasons 4.2BSD introduced the automatic restart feature is that sometimes we don't know that the input or output device is a slow device. If the program we write can be used interactively, then it might be reading or writing a slow device, since terminals fall into this category. If we catch signals in this program, and if the system doesn't provide the restart capability, then we have to test every read or write for the interrupted error return and reissue the read or write.</p>
<p class="docText"><a class="docLink" href="#ch10fig03">Figure 10.3</a> summarizes the signal functions and their semantics provided by the various implementations.</p>
<a name="ch10fig03"></a><p><table cellspacing="0" class="allBorders" border="1" RULES="all" cellpadding="4"><caption><h5 class="docTableTitle">Figure 10.3. Features provided by various signal implementations</h5></caption><colgroup><col width="75"><col width="150"><col width="75"><col width="75"><col width="125"></colgroup><thead><tr><th class="thead" scope="col" align="center" valign="middle"><p class="docText"><span class="docEmphRoman">Functions</span></p></th><th class="thead" scope="col" align="center" valign="middle"><p class="docText"><span class="docEmphRoman">System</span></p></th><th class="thead" scope="col" align="center" valign="middle"><p class="docText"><span class="docEmphRoman">Signal handler remains installed</span></p></th><th class="thead" scope="col" align="center" valign="middle"><p class="docText"><span class="docEmphRoman">Ability to block signals</span></p></th><th class="thead" scope="col" align="center" valign="middle"><p class="docText"><span class="docEmphRoman">Automatic restart of interrupted system calls?</span></p></th></tr></thead><tr><td class="docTableCell" align="center" valign="middle" rowspan="4"><p class="docText"><tt>signal</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText">ISO C, POSIX.1</P></TD><td class="docTableCell" align="center" valign="top"><p class="docText">unspecified</P></TD><TD class="docTableCell" align="center" valign="top"><p class="docText">unspecified</p></TD><TD class="docTableCell" align="center" valign="top"><p class="docText">unspecified</P></td></TR><tr><TD class="docTableCell" align="left" valign="top"><p class="docText">V7, SVR2, SVR3, SVR4, Solaris</P></TD><td class="docTableCell" align="left" valign="top">&nbsp;</TD><TD class="docTableCell" align="left" valign="top">&nbsp;</td><TD class="docTableCell" align="center" valign="top"><p class="docText">never</P></td></tr><tr><td class="docTableCell" align="left" valign="top"><p class="docText">4.2BSD</P></td><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></TD><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="docTableCell" align="center" valign="top"><p class="docText">always</p></td></tr><tr><td class="docTableCell" align="left" valign="top"><p class="docText">4.3BSD, 4.4BSD, FreeBSD, Linux, Mac OS X</p></td><td class="docTableCell" align="center" valign="middle"><p class="docText">&#8226;</p></td><td class="docTableCell" align="center" valign="middle"><p class="docText">&#8226;</p></td><TD class="docTableCell" align="center" valign="top"><p class="docText">default</P></td></TR><TR><TD class="docTableCell" align="center" valign="middle" rowspan="2"><p class="docText"><tt>sigset</tt></p></TD><TD class="docTableCell" align="left" valign="top"><p class="docText">XSI</P></td><TD class="docTableCell" align="center" valign="middle"><p class="docText">&#8226;</p></TD><TD class="docTableCell" align="center" valign="middle"><p class="docText">&#8226;</P></td><TD class="docTableCell" align="center" valign="top"><p class="docText">unspecified</P></td></TR><TR><td class="docTableCell" align="left" valign="top"><p class="docText">SVR3, SVR4, Linux, Solaris</p></td><td class="docTableCell" align="center" valign="middle"><p class="docText">&#8226;</P></td><TD class="docTableCell" align="center" valign="middle"><p class="docText">&#8226;</p></TD><td class="docTableCell" align="center" valign="middle"><p class="docText">never</p></td></tr><tr><td class="docTableCell" align="center" valign="middle" rowspan="2"><p class="docText"><tt>sigvec</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText">4.2BSD</p></td><td class="docTableCell" align="center" valign="middle"><p class="docText">&#8226;</p></td><td class="docTableCell" align="center" valign="middle"><p class="docText">&#8226;</p></td><TD class="docTableCell" align="center" valign="top"><p class="docText">always</P></td></TR><TR><TD class="docTableCell" align="left" valign="top"><p class="docText">4.3BSD, 4.4BSD, FreeBSD, Mac OS X</p></TD><TD class="docTableCell" align="center" valign="middle"><p class="docText">&#8226;</P></td><TD class="docTableCell" align="center" valign="middle"><p class="docText">&#8226;</p></TD><TD class="docTableCell" align="center" valign="middle"><p class="docText">default</P></td></TR><TR><td class="docTableCell" align="center" valign="middle" rowspan="2"><p class="docText"><tt>sigaction</tt></P></TD><td class="docTableCell" align="left" valign="top"><p class="docText">POSIX.1</p></td><td class="docTableCell" align="center" valign="middle"><p class="docText">&#8226;</P></td><TD class="docTableCell" align="center" valign="middle"><p class="docText">&#8226;</p></TD><td class="docTableCell" align="center" valign="top"><p class="docText">unspecified</p></td></tr><tr><td class="docTableCell" align="left" valign="top"><p class="docText">XSI, 4.4BSD, SVR4, FreeBSD, Mac OS X, Linux, Solaris</p></td><td class="docTableCell" align="center" valign="middle"><p class="docText">&#8226;</p></td><td class="docTableCell" align="center" valign="middle"><p class="docText">&#8226;</p></td><td class="docTableCell" align="center" valign="middle"><p class="docText">optional</p></td></TR></table></P><br>
<blockquote>
<p class="docText">We don't discuss the older <tt>sigset</tt> and <tt>sigvec</tt> functions. Their use has been superceded by the <tt>sigaction</tt> function; they are included only for completeness. In contrast, some implementations promote the <tt>signal</tt> function as a simplified interface to <tt>sigaction</tt>.</P>
</blockquote>
<p class="docText"><a name="idd1e71525"></a><a name="idd1e71530"></a><a name="idd1e71535"></a><a name="idd1e71540"></a><a name="idd1e71545"></a><a name="idd1e71548"></a><a name="idd1e71553"></a><a name="idd1e71558"></a><a name="idd1e71563"></a>Be aware that UNIX systems from other vendors can have values different from those shown in this figure. For example, <tt>sigaction</tt> under SunOS 4.1.2 restarts an interrupted system call by default, different from the platforms listed in <a class="docLink" href="#ch10fig03">Figure 10.3</a>.</P>
<p class="docText">In <a class="docLink" href="ch10lev1sec14.html#ch10fig18">Figure 10.18</a>, we provide our own version of the <tt>signal</tt> function that automatically tries to restart interrupted system calls (other than for the <tt>SIGALRM</tt> signal). In <a class="docLink" href="ch10lev1sec14.html#ch10fig19">Figure 10.19</a>, we provide another function, <tt>signal_intr</tt>, that tries to never do the restart.</P>
<p class="docText">We talk more about interrupted system calls in <a class="docLink" href="ch14lev1sec5.html#ch14lev1sec5">Section 14.5</a> with regard to the <tt>select</tt> and <tt>poll</tt> functions.</p>

<a href="17021535.html"><img src="images/pixel.gif" alt="" width="1" height="1" border="0"></a><UL></UL></TD></tr></table>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/team.gif" width="60" height="17" border="0" align="absmiddle"  alt="Team BBL"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=ch10lev1sec4.html><img src="images/prev.gif" width="60" height="17" border="0" align="absmiddle" alt="Previous Page"></a>
<a href=ch10lev1sec6.html><img src="images/next.gif" width="60" height="17" border="0" align="absmiddle" alt="Next Page"></a>
</div></td></tr></table>
</body></html><br>
<table width="100%" cellspacing="0" cellpadding="0"
style="margin-top: 0pt; border-collapse: collapse;"> 
<tr> <td align="right" style="background-color=white; border-top: 1px solid gray;"> 
<a href="http://www.zipghost.com/" target="_blank" style="font-family: Tahoma, Verdana;
 font-size: 11px; text-decoration: none;">The CHM file was converted to HTM by Trial version of <b>ChmD<!--199-->ecompiler</b>.</a>
</TD>
</TR><tr>
<td align="right" style="background-color=white; "> 
<a href="http://www.etextwizard.com/download/cd/cdsetup.exe" target="_blank" style="font-family: Tahoma, Verdana;
 font-size: 11px; text-decoration: none;">Download <b>ChmDec<!--199-->ompiler</b> at: http://www.zipghost.com</a>
</TD></tr></table>
